import lombok.extern.slf4j.Slf4j;

import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 测试定时调用
 *
 * @author 管子
 * @date 2025/5/3 22:57
 * @description: TestTimer 类
 */
@Slf4j
public class TestTimer {

    public static void main(String[] args) {
//        testTimer();
        ScheduledExecutorService pool = Executors.newScheduledThreadPool(2);  // 改成了2个线程，所以可以多任务同时执行，如果1还是串行
//        delayExecute(pool);

        // 测试3：定时执行
        // 启动后延迟1s开始执行，每隔1s执行一次，但是如果没有执行完任务，会串行执行
//        pool.scheduleAtFixedRate(() -> {
//            log.info("running......");
//            try {
//                Thread.sleep(2000L);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//        }, 1, 1, TimeUnit.SECONDS);

        // scheduleWithFixedDelay()方法和scheduleAtFixedRate()方法的不同在于第三个参数delay
        // delay的意思是，上一次任务执行完之后，再间隔多久才执行下一次任务，和上一个方法的区别就是，上一个方法是隔多少绝对时间继续走，这个是相对时间继续走
        pool.scheduleWithFixedDelay(() -> {
            log.info("running......");
            try {
                Thread.sleep(2000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, 1, 1, TimeUnit.SECONDS);
    }

    /**
     * 测试2：ScheduledExecutorService 的延时执行测试
     * @param pool
     */
    private static void delayExecute(ScheduledExecutorService pool) {
        pool.schedule(() -> {
            log.info("task 1");
            try {
                Thread.sleep(2000L);
                int i = 10 / 0;  // ScheduledExecutorService 不会被异常导致其他任务不执行
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, 1, TimeUnit.SECONDS);

        pool.schedule(() -> {
            log.info("task 2");
        }, 1, TimeUnit.SECONDS);
    }

    /**
     * 测试1：原始的定时任务调度
     */
    public static void testTimer() {
        Timer timer = new Timer();
        TimerTask task1 = new TimerTask() {
            @Override
            public void run() {
                log.info("task 1");
                try {
                    Thread.sleep(2000);  // 定时任务只能串行执行，task2 会被等待
                    int i = 10 / 0; // 这里报了异常 task2 甚至不会被调用了，所以Timer很脆弱
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        TimerTask task2 = new TimerTask() {
            @Override
            public void run() {
                log.info("task 2");
            }
        };

        log.info("start......");
        timer.schedule(task1, 1000);
        timer.schedule(task2, 1000);
    }

}
